<template>
	<view>
		<view class="d-flex justify-content-between align-items-center update-box mt-40 mr-32">
			<!-- 可用iconfont -->
			<image @click="devicePosition=!devicePosition" class="camera-change-image" mode="widthFix"
				src="../../static/购.jpg"></image>
		</view>
		<view class="head-image-box w-100 text-center position-relative">
			<!-- resolution：获取人脸图片后的清晰度 low:低 -->
			<camera v-if='isAuthCamera' :device-position="devicePosition ?'back': 'front'" class="camera" flash="off"
				resolution='low' />

			<view class="title mt-40" v-show="!tempImg && tipsText">{{ tipsText }}</view>
			<cover-view class="cover-box" v-show="isShow">
				<!-- <cover-image class="image-box" src="../../static/分类.png"></cover-image> -->

				<!-- cover-view 不支持动画所以只能变通的形式实现 -->
				<cover-image :style="'transform: translateY('+translateY+'rpx);'" class="line"
					src="../../static/购.jpg"></cover-image>
				<!-- <cover-view class="line"></cover-view> -->
			</cover-view>
		</view>
	</view>
</template>

<script>
	import upng from "../../utils/UPNG.js"

	export default {
		name: "faceSwiping",
		data() {
			return {
				isShow: false,
				tipsText: '', // 错误文案提示
				tempImg: '', // 本地图片路径
				cameraEngine: null, // 相机引擎
				devicePosition: true, // 摄像头朝向
				isAuthCamera: true, // 是否拥有相机权限
				isVerify: false,
				translateY: -24,
				timer: null,
				isFlag: true,
				origin: null
			}
		},
		onShow: function() {
			this.isVerify = false;
			this.tipsText = "";
			this.isFlag = true;
		},
		onLoad(options) {
			this.origin = options.origin;

			this.initData();
			this.lineAnimation()
		},
		onUnload: function() {
			clearInterval(this.timer);
			this.timer = null;
			this.isFlag = false;
		},
		methods: {
			// 初始化相机引擎
			initData() {
				// #ifdef MP-WEIXIN
				// 1、初始化人脸识别
				wx.initFaceDetect()
				// 2、创建 camera 上下文 CameraContext 对象
				this.cameraEngine = wx.createCameraContext();
				this.isShow = true;
				// 3、获取 Camera 实时帧数据
				const listener = this.cameraEngine.onCameraFrame((frame) => {
					if (this.tempImg) {
						return;
					}
					// 4、人脸识别，使用前需要通过 wx.initFaceDetect 进行一次初始化，推荐使用相机接口返回的帧数据
					wx.faceDetect({
						frameBuffer: frame.data,
						width: frame.width,
						height: frame.height,
						enablePoint: true,
						enableConf: true,
						enableAngle: true,
						enableMultiFace: true,
						success: (faceData) => {

							if (this.isVerify) return
							let face = faceData.faceInfo[0]
							if (face.x == -1 || face.y == -1) {
								this.tipsText = '检测不到人'
							}
							if (faceData.faceInfo.length > 1) {
								this.tipsText = '请保证只有一个人'
							} else {
								const {
									pitch,
									roll,
									yaw
								} = face.angleArray;
								const standard = 0.5
								if (Math.abs(pitch) >= standard || Math.abs(roll) >= standard ||
									Math.abs(yaw) >= standard) {
									this.tipsText = '请平视摄像头'
								} else if (face.confArray.global <= 0.8 || face.confArray.leftEye <=
									0.8 || face.confArray.mouth <= 0.8 || face.confArray.nose <= 0.8 ||
									face.confArray.rightEye <= 0.8) {
									this.tipsText = '请勿遮挡五官'
								} else {
									this.tipsText = '校验中...'
									this.isVerify = true;

									// 太快获取的人脸可能比较抽象,给用户一个准备时间
									setTimeout(() => {
										//借助upng把流转为二进制数据
										let pngData = upng.encode([frame.data], frame.width,
												frame.height),
											base64 = arrayBufferToBase64(pngData);

										// 获取到base64后可以已上传，展示，或保存到本地

										var imageType = getImageType();

										function getImageType() {
											let type = "center"
											if (face.y / frame.height < 0.3333) {
												type = "top"
											} else if (face.y / frame.height > 0.6666) {
												type = "bottom"
											}
											return type;
										}

										//二进制转base64
										function arrayBufferToBase64(buffer) {
											var binary = '';
											var bytes = new Uint8Array(buffer);
											var len = bytes.byteLength;
											for (var i = 0; i < len; i++) {
												// unicode编码还原
												binary += String.fromCharCode(bytes[i]);
											}
											return "data:image/png;base64," + btoa(binary);
										}

										// 小程序没有window对象，需手动实现btoa()方法
										// 作用: 字符转base64
										function btoa(string) {
											const b64 =
												"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
											string = String(string);
											var bitmap, a, b, c,
												result = "",
												i = 0,
												rest = string.length %
												3; // To determine the final padding

											for (; i < string.length;) {
												if ((a = string.charCodeAt(i++)) > 255 ||
													(b = string.charCodeAt(i++)) > 255 ||
													(c = string.charCodeAt(i++)) > 255)
													throw new TypeError(
														"Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range."
													);

												bitmap = (a << 16) | (b << 8) | c;
												result += b64.charAt(bitmap >> 18 & 63) + b64
													.charAt(bitmap >> 12 & 63) +
													b64.charAt(bitmap >> 6 & 63) + b64.charAt(
														bitmap & 63);
											}

											return rest ? result.slice(0, rest - 3) + "==="
												.substring(rest) : result;
										};

										this.tipsText = '校验成功'
										setTimeout(() => {
											this.clickPushDetail(imageType);
										}, 50)
									}, 300)
								}
							}
						},
						fail: (err) => {
							if (this.isVerify) return
							if (err.x == -1 || err.y == -1) {
								this.tipsText = '检测不到人'
							} else {
								this.tipsText = err.errMsg || '网络错误，请退出页面重试'
							}
						},
					})
				})
				// 5、开始监听帧数据
				listener.start()
				// #endif
			},

			clickPushDetail(imageType) {
				if (!this.isFlag) return
				uni.navigateTo({
					url:"/subUserInfo/setting/setting"
				})
				// 可以跳转到详情页面
			},
			lineAnimation() {
				if (this.timer) return
				this.timer = setInterval(() => {
					this.translateY += 3;
					if (this.translateY >= 460) {
						this.translateY = 10;
					}
				}, 12)
			},
		}
	}
</script>

<style>
	page {
		background-color: #000000;
	}
</style>
<style lang="scss" scoped>
	.d-flex {
		display: flex;
	}

	.justify-content-center {
		justify-content: center;
	}

	.align-items-center {
		align-items: center;
	}


	.camera-change-image {
		width: 48rpx;
		margin-left: 40rpx;
	}

	.mr-32 {
		margin-right: 32rpx;
	}

	.mt-40 {
		margin-top: 40rpx;
	}

	.text-center {
		text-align: center;
	}

	.position-relative {
		position: relative;
	}

	.w-100 {
		width: 100%;
	}

	.update-box {
		color: #ffffff;
	}

	.head-image-box {
		position: absolute;
		top: 10vh;
		color: white;

		.camera {
			width: 100%;
			height: 872rpx;
		}

		.title {
			font-size: 48rpx;
			font-weight: bold;
		}

		.cover-box {
			position: absolute;
			top: 40%;
			left: 50%;
			transform: translate(-50%, -50%);
			width: 500rpx;
			height: 500rpx;
		}

		.image-box {
			width: 100%;
			height: 100%;
		}

		.line {
			position: absolute;
			top: 0rpx;
			left: 8rpx;
			right: 8rpx;
			width: auto;
			height: 10rpx;
			// transform: translateY(-24rpx);
			// animation: radar-beam 1.5s infinite;
			// background: linear-gradient(180deg, rgba(13, 110, 217, 0) 0%, rgba(13, 110, 217, 0.4000) 100%);
			z-index: 2;
		}

		// @keyframes radar-beam {
		// 	0% {
		// 		transform: translateY(24rpx);
		// 	}

		// 	100% {
		// 		transform: translateY(450rpx);
		// 	}
		// }

	}
</style>